home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1995 October / EnigmA AMIGA RUN 01 (1995)(G.R. Edizioni)(IT)[!][issue 1995-10][Aminet 7].iso / Aminet / comm / tcp / wu_ftpd_37_21.lha / wu-ftpd / src / private.c < prev    next >
C/C++ Source or Header  |  1994-08-11  |  9KB  |  299 lines

  1. /* Copyright (c) 1993, 1994  Washington University in Saint Louis
  2.  * All rights reserved.
  3.  *
  4.  * Redistribution and use in source and binary forms, with or without
  5.  * modification, are permitted provided that the following conditions are
  6.  * met: 1. Redistributions of source code must retain the above copyright
  7.  * notice, this list of conditions and the following disclaimer. 2.
  8.  * Redistributions in binary form must reproduce the above copyright notice,
  9.  * this list of conditions and the following disclaimer in the documentation
  10.  * and/or other materials provided with the distribution. 3. All advertising
  11.  * materials mentioning features or use of this software must display the
  12.  * following acknowledgement: This product includes software developed by the
  13.  * Washington University in Saint Louis and its contributors. 4. Neither the
  14.  * name of the University nor the names of its contributors may be used to
  15.  * endorse or promote products derived from this software without specific
  16.  * prior written permission.
  17.  *
  18.  * THIS SOFTWARE IS PROVIDED BY WASHINGTON UNIVERSITY AND CONTRIBUTORS
  19.  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  20.  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  21.  * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASHINGTON
  22.  * UNIVERSITY OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  23.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  24.  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  25.  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  26.  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  27.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  28.  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  29.  * POSSIBILITY OF SUCH DAMAGE.
  30.  */
  31.  
  32. #ifndef NO_PRIVATE
  33.  
  34. #include "config.h"
  35.  
  36. #include <stdio.h>
  37. #include <errno.h>
  38. #include <string.h>
  39. #ifdef SYSSYSLOG
  40. #include <sys/syslog.h>
  41. #else
  42. #include <syslog.h>
  43. #endif
  44. #include <grp.h>
  45.  
  46. #include <sys/types.h>
  47. #include <sys/stat.h>
  48. #include <sys/file.h>
  49.  
  50. #include "pathnames.h"
  51. #include "extensions.h"
  52.  
  53. #define MAXGROUPLEN 100
  54. char *passbuf = NULL;
  55. char groupname[MAXGROUPLEN];
  56. int group_given = 0;
  57.  
  58. struct acgrp {
  59.     char  gname[MAXGROUPLEN];    /* access group name */
  60.     char  gpass[MAXGROUPLEN];    /* access group password */
  61.     char  gr_name[MAXGROUPLEN];  /* group to setgid() to */
  62.     gid_t gr_gid;
  63.     struct acgrp *next;
  64. };
  65.  
  66. struct acgrp *privptr;
  67.  
  68. extern int lgi_failure_threshold,
  69.   autospout_free;
  70. extern char remotehost[],
  71.   remoteaddr[],
  72.  *autospout;
  73. int group_attempts;
  74.  
  75. void
  76. parsepriv(void)
  77. {
  78.     char *ptr;
  79.     char *acptr = passbuf,
  80.      *line;
  81.     char **argv[51],
  82.     **ap = (char **) argv,
  83.      *p,
  84.      *val;
  85.     struct acgrp *aptr;
  86.     struct group *gr;
  87.  
  88.     if (!passbuf || !(*passbuf))
  89.         return;
  90.  
  91.     /* build list, initialize to zero. */
  92.     privptr = (struct acgrp *) calloc(1, sizeof(struct acgrp));
  93.  
  94.     /* read through passbuf, stripping comments. */
  95.     while (*acptr != '\0') {
  96.         line = acptr;
  97.         while (*acptr && *acptr != '\n')
  98.             acptr++;
  99.         *acptr++ = '\0';
  100.  
  101.         /* deal with comments */
  102.         if ((ptr = strchr(line, '#')) != NULL)
  103.             *ptr = '\0';
  104.  
  105.         if (*line == '\0')
  106.             continue;
  107.  
  108.         ap = (char **) argv;
  109.  
  110.         /* parse the lines... */
  111.         for (p = line; p != NULL;) {
  112.             while ((val = (char *) strsep(&p, ":\n")) != NULL
  113.                    && *val == '\0') ;
  114.             *ap = val;
  115.             if (**ap == ' ')
  116.                 *ap = NULL;
  117.             *ap++;
  118.         }
  119.         *ap = 0;
  120.  
  121.         if ((gr = getgrnam((char *) argv[2])) != NULL)  {
  122.             aptr = (struct acgrp *) calloc(1, sizeof(struct acgrp));
  123.             
  124.             /* if we didn't read 3 things, skip that line... */
  125.  
  126.             /* add element to beginning of list */
  127.  
  128.             aptr->next = privptr;
  129.             privptr = aptr;
  130.  
  131.             strcpy(aptr->gname, (char *) argv[0]);
  132.             strcpy(aptr->gpass, (char *) argv[1]);
  133.             strcpy(aptr->gr_name, (char *) argv[2]);
  134.             aptr->gr_gid = gr->gr_gid;
  135.         }
  136.     }
  137. }
  138.  
  139. /*************************************************************************/
  140. /* FUNCTION  : priv_setup                                                */
  141. /* PURPOSE   : Set things up to use the private access password file.    */
  142. /* ARGUMENTS : path, the path to the private access password file        */
  143. /*************************************************************************/
  144.  
  145. void
  146. priv_setup(char *path)
  147. {
  148.     FILE *prvfile;
  149.     struct stat finfo;
  150.  
  151.     passbuf = (char *) NULL;
  152.  
  153.     if (stat(path, &finfo) != 0) {
  154.         syslog(LOG_ERR, "cannot stat private access file %s: %s", path,
  155.                strerror(errno));
  156.         return;
  157.     }
  158.     if ((prvfile = fopen(path, "r")) == NULL) {
  159.         if (errno != ENOENT)
  160.             syslog(LOG_ERR, "cannot open private access file %s: %s",
  161.                    path, strerror(errno));
  162.         return;
  163.     }
  164.     if (finfo.st_size == 0) {
  165.         passbuf = (char *) calloc(1, 1);
  166.     } else {
  167.         if (!(passbuf = malloc((unsigned) finfo.st_size + 1))) {
  168.             (void) syslog(LOG_ERR, "could not malloc passbuf (%d bytes)",
  169.                           finfo.st_size + 1);
  170.             return;
  171.         }
  172.         if (!fread(passbuf, (size_t) finfo.st_size, 1, prvfile)) {
  173.             (void) syslog(LOG_ERR, "error reading private access file %s: %s",
  174.                           path, strerror(errno));
  175.         }
  176.         *(passbuf + finfo.st_size) = '\0';
  177.     }
  178.  
  179.     (void) parsepriv();
  180. }
  181.  
  182. /*************************************************************************/
  183. /* FUNCTION  : priv_getent                                               */
  184. /* PURPOSE   : Retrieve an entry from the in-memory copy of the group    */
  185. /* access file.                                              */
  186. /* ARGUMENTS : pointer to group name                                     */
  187. /*************************************************************************/
  188.  
  189. struct acgrp *
  190. priv_getent(char *group)
  191. {
  192.     struct acgrp *ptr;
  193.  
  194.     for (ptr = privptr; ptr; ptr=ptr->next)
  195.         if (!strcmp(group, ptr->gname))
  196.             return(ptr);
  197.  
  198.     return (NULL);
  199. }
  200.  
  201. /*************************************************************************/
  202. /* FUNCTION  : priv_group                                                */
  203. /* PURPOSE   :                                                           */
  204. /* ARGUMENTS :                                                           */
  205. /*************************************************************************/
  206.  
  207. void
  208. priv_group(char *group)
  209. {
  210.     if (strlen(group) < MAXGROUPLEN) {
  211.         strncpy(groupname, group, MAXGROUPLEN);
  212.         group_given = 1;
  213.         reply(200, "Request for access to group %s accepted.", group);
  214.     } else {
  215.         group_given = 0;
  216.         reply(500, "Illegal group name");
  217.     }
  218.  
  219. }
  220.  
  221. /*************************************************************************/
  222. /* FUNCTION  : priv_gpass                                                */
  223. /* PURPOSE   : validate the group access request, and if OK place user   */
  224. /* in the proper group.                                      */
  225. /* ARGUMENTS : group access password                                     */
  226. /*************************************************************************/
  227.  
  228. void
  229. priv_gpass(char *gpass)
  230. {
  231.     char *xgpass,
  232.      *salt;
  233. #ifndef NO_CRYPT_PROTO
  234.     char *crypt(const char *, const char *);
  235. #endif
  236.     struct acgrp *grp;
  237.     uid_t uid;
  238.     gid_t gid;
  239.  
  240.     if (group_given == 0) {
  241.         reply(503, "Give group name with SITE GROUP first.");
  242.         return;
  243.     }
  244. #ifdef AMIGA
  245.     if(UserGroupBase)
  246.     {
  247. #endif
  248.     /* OK, now they're getting a chance to specify a password.  Make them
  249.      * give the group name again if they fail... */
  250.     group_given = 0;
  251.  
  252.     if (passbuf != NULL) {
  253.         grp = priv_getent(groupname);
  254.  
  255.         if (grp == NULL)
  256.             salt = "xx";
  257.         else
  258.             salt = grp->gpass;
  259.  
  260.         xgpass = crypt(gpass, salt);
  261.     } else
  262.         grp = NULL;
  263.  
  264.     /* The strcmp does not catch null passwords! */
  265.     if (grp == NULL || *grp->gpass == '\0' || strcmp(xgpass, grp->gpass)) {
  266.         reply(530, "Group access request incorrect.");
  267.         grp = NULL;
  268.         if (++group_attempts >= lgi_failure_threshold) {
  269.             syslog(LOG_NOTICE,
  270.                    "repeated group access failures from %s [%s], group %s",
  271.                    remotehost, remoteaddr, groupname);
  272.             exit(0);
  273.         }
  274.         sleep(group_attempts);  /* slow down password crackers */
  275.         return;
  276.     }
  277.  
  278.     uid = geteuid();
  279.     gid = grp->gr_gid;
  280.  
  281.     seteuid(0);
  282.     setegid(gid);
  283.     seteuid(uid);
  284.  
  285.     reply(200, "Group access enabled.");
  286.     group_attempts = 0;
  287. #ifdef AMIGA
  288.     }
  289.     /* We always fail for group access if MultiUser
  290.      * is installed because it has very limited group
  291.      * capabilities.
  292.      */
  293.     else
  294.         reply(530, "Group access request incorrect.");
  295.       
  296. #endif
  297. }
  298. #endif /* !NO_PRIVATE */
  299.